
(function() {

//Privte cached data....
var sieve = [];
var primes= [2];
var sieveSize = 2;
var maxCachedPrime = 2;

sieve[1]=1;
sieve[2]=0;


JEuler.math.PrimeUtils={

    sievePrime : function(size, bLog) {
        if(size<=sieveSize) return;
        sieveSize = size;
        for(var i=2; i<=size; i++) {
            for(var j=(i+i); j<=size; j=j+i) {
                sieve[j] = 1;
            }
        }
        
        for(var i=maxCachedPrime+1; i<=size; i++) {
            if(sieve[i] != 1) primes.push(i);
        }
        maxCachedPrime = primes[primes.length-1];
        
    },

    isPrime : function(n) {
        if(n<=maxCachedPrime) return sieve[n] !=1;
        var sqrt = Math.floor(Math.sqrt(n));
        for(var i=0; i<primes.length; i++) {
            if(primes[i]>=sqrt) return true;
            if(n%primes[i]==0) return false;
        }
        
        if(sqrt>maxCachedPrime) {
            for(var i=maxCachedPrime+2; i<=sqrt+1; i++) {
                if(n%i==0) return false;
            }
            return true;
        }
        
    },
    
    printCachedPrimes : function(v) {
        v = (v || "vv").split("").length;
        if(v>=1) JEuler.system.print('[Cached Primes, '+primes.length+'/'+ sieveSize +']');
        if(v>=2) JEuler.system.print(primes.join(",").replace(new RegExp("(.{80})", "ig"), "$1\n"));
    },
    
    getPrimePool : function() {
        return primes;
    }
};

JEuler.math.Permutation = function(digitalStr) {
    this.digits = digitalStr.split("").sort();
    this.permutations = [];
};

JEuler.math.Permutation.prototype = {

    _greatThen : function(a, b) {
        return this.digits[a]>this.digits[b];
    },
    
    _swap : function(a, b) {
        var t = this.digits[a];
        this.digits[a] = this.digits[b];
        this.digits[b] = t;
    },
    
    _reverse : function(a, b) {
        b = b || this.digits.length-1;
        for(var i=0; i<(b-a+1)/2; i++) {
            this._swap(a+i, b-i);
        }
    },
    
    getCurrent : function() {
    },

    getAll : function(bPrint) {
        do {
            
            if(bPrint) {
                JEuler.system.print(this.digits.join(""));
            };
            
        } while (this.next() != false);  
        return this.permutations;
    },
    
    next : function() {
    
        var postLeft=-1, postRight=-1, l=this.digits.length;;

        for(var i=l-1; i>0; i--) {
            if(this._greatThen(i, i-1)) {
                postLeft = i-1;
                break;
            }
        }
        
        if(postLeft <0) {
            return false;
        }
        
        for(var i=l-1; i>=postLeft; i--) {
            if(this._greatThen(i, postLeft)) {
                postRight = i;
                break;
            }
        }
             
        this._swap(postLeft, postRight);
        this._reverse(postLeft+1);
        
        var permu = this.digits.join("");
        this.permutations.push(permu);
        return permu;      
    }
};

JEuler.math.gcd = function(a,b) {
    var tmp, p=a, q=b;
    if(b>a) { p=b; q=a };
    tmp = p%q;
    do {
        if(tmp==0) return q;
        p = q;
        q = tmp;
        tmp = p%q;
    } while(tmp!=0);
    return q;
};



})();
